package com.gangwangchina.android.contactlib.model;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.gangwangchina.android.contactlib.ContactsInterface;
import com.gangwangchina.android.contactlib.exceptions.NoIdException;



import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;

public class Person {
	
	public static final String _ID = ContactsContract.Contacts._ID;
	public static final String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;

	public long id;
	private String displayName;
	private List<PersonContact> rawContacts;	

	/**
	 * Creates an object representation of a Person that is present in the database
	 * @param id
	 * @param displayName
	 * @return
	 */
	public static Person recoverPerson(long id, String displayName){
		return new Person(id, displayName);
	}
	
	/**
	 * Creates an object representation of a PersonContact that is present in the database and loads its contacts
	 * @param id
	 * @param displayName
	 * @param ctx
	 * @return
	 * @throws NoIdException
	 */
	public static Person recoverPersonAndContacts(long id, String displayName, Context ctx) throws NoIdException{
		Person p = new Person(id, displayName);
		p.loadPersonContacts(ctx);
		return p;
	}
	
	/**
	 * Creates a new Person
	 * @param displayName
	 */
	private Person(long id, String displayName){
		this.id = id;
		this.displayName = displayName;
	}


	/**
	 * @return the display name of the person
	 */
	public String displayName(){
		return displayName;
	}

	/**
	 * Loads the PersonContacts of the Person.
	 * @param ctx the context in which access to the database will be made
	 * @throws NoIdException 
	 */
	public void loadPersonContacts(Context ctx) throws NoIdException{
		if(id==ContactsInterface.INVALID_ID||id==ContactsInterface.NO_ID) throw new NoIdException(id);
		rawContacts = new ArrayList<PersonContact>();
		Cursor c = rawContactsCursor(ctx);
		PersonContact pc;
		while(c.moveToNext()){
			pc = PersonContact.recoverPersonContact(this.id, c.getString(1), c.getString(2));
			pc.id = c.getLong(0);
			pc.fill(ctx);
			rawContacts.add(pc);
		}
		c.close();

	}

	/**
	 * Links a PersonContact to the current Person
	 * @param pc
	 */
	public void addPersonContact(PersonContact pc){
		if(rawContacts==null) rawContacts = new ArrayList<PersonContact>();
		rawContacts.add(pc);
	}

	/**
	 * @return an iterator over the Person's PersonContacts
	 */
	public Iterator<PersonContact> personContactsIterator(){
		if(rawContacts==null) return null;
		return rawContacts.iterator();
	}

	private Cursor rawContactsCursor(Context ctx){
		String[] projection = { RawContacts._ID, RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE};
		String selection = RawContacts.CONTACT_ID + "=?";
		String[] selectArgs = { String.valueOf(id)};
		return ctx.getContentResolver().query(RawContacts.CONTENT_URI, projection, selection, selectArgs, null);
	}

	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append(id).append(',');
		sb.append(displayName);
		if(rawContacts!=null){
			for(Iterator<PersonContact> it = rawContacts.iterator(); it.hasNext();)
				sb.append('\n').append(it.next().toString());
		}
		return sb.toString();
	}

}